package com.plian.system.service.zcgl.check;

import com.plian.Tools.CacheUtil;
import com.plian.Tools.EncryptUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.system.bean.zcgl.ZcglStaffManagementBean;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.entity.zcgl.ZcglStaffManagement;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.excel.ImportResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.BaseConstant.BASE64_KEY;

@AllArgsConstructor
@Slf4j
public class ZcglStaffManagementCheckData {

    private final static String OBJECT_MSG = "未找到对应对象!";
    /**
     * 人员档案导入 主表校验
     * @param readExcels Excel导入的员工数据
     * @param staffFilesList 现有的所有人员列表，用于查重校验
     * @param progressId 流程key
     * @param codeMap 员工档案中所有code转id的参照字典
     * @param nameMap 员工档案中所有name转id的参照字典(指单位)
     * @param deptUnitMap 员工档案中所有部门名称转id的参照字典(部门与单位存在关联依赖)
     * @param isCover 是否为导入覆盖（true:覆盖，false:新增）
     * @return ImportResult
     */
    public static ImportResult checkStaffData(List<Object> readExcels, List<ZcglStaffManagement> staffFilesList, String progressId,
                                              HashMap<String, List<String>> codeMap, HashMap<String, Map<String,String>> nameMap,
                                              HashMap<String,Map<String,Long>> deptUnitMap, HashMap<String,Map<String,String>> deptUnitCodeMap, Boolean isCover) {
        ImportResult importResult = new ImportResult(true,"");
        List<Object> objectStaffFilesList= new ArrayList<>(staffFilesList);
        StringBuilder msg = new StringBuilder();

        List<String> codeList = new ArrayList<>();

        //数据判空及数据类型校验
        for (Object readExcel : readExcels) {
            ZcglStaffManagementBean staffExcelBean =(ZcglStaffManagementBean)readExcel;
            int index = readExcels.indexOf(readExcel);
            //编码判重队列
            codeList.add(staffExcelBean.getStaffCode());
            //判空
            msg.append(ImportExcelUtil.checkEmpty("2", "证件号", staffExcelBean.getStaffCode(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "姓名", staffExcelBean.getStaffName(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "证件类型", staffExcelBean.getDocumentTypeId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "性别", staffExcelBean.getGenderId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "出生日期", staffExcelBean.getBirthday(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "民族", staffExcelBean.getNationId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "政治面貌", staffExcelBean.getPoliticCountenanceId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "健康状况", staffExcelBean.getHealthConditionId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "单位名称", staffExcelBean.getCompanyNameId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "最高学历", staffExcelBean.getEducationalId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "参加工作时间", staffExcelBean.getWorkTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "本单位入职时间", staffExcelBean.getCompanyInitiationTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "部门名称", staffExcelBean.getDepartmentNameId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "管理类别", staffExcelBean.getManagementCategoryId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "职务名称", staffExcelBean.getJobNameId(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "籍贯", staffExcelBean.getNativePlace(), index).getMsg());
//            msg.append(ImportExcelUtil.checkEmpty("2", "入党/团时间", staffExcelBean.getJoinPartyTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "联系电话", staffExcelBean.getTelephone(), index).getMsg());
            msg.append(ImportExcelUtil.checkEmpty("2", "任现职时间", staffExcelBean.getTenureTime(), index).getMsg());

            //判断数据类型
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "证件类型",
                    staffExcelBean.getDocumentTypeId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "性别",
                    staffExcelBean.getGenderId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "民族",
                    staffExcelBean.getNationId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "政治面貌",
                    staffExcelBean.getPoliticCountenanceId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "国籍",
                    staffExcelBean.getNationalityId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "婚姻状态",
                    staffExcelBean.getNationalityId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "最高学历",
                    staffExcelBean.getEducationalId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "最高学位",
                    staffExcelBean.getDegreeId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "管理类别",
                    staffExcelBean.getManagementCategoryId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "编制类型",
                    staffExcelBean.getCompilationTypeId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "人员类型",
//				staffExcelBean.getStaffTypeId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "人员类别",
//				staffExcelBean.getStaffCategoryId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职务类别",
                    staffExcelBean.getJobCategoryId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职级",
                    staffExcelBean.getRankId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职等",
//				staffExcelBean.getGradePositionsId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "异动事件",
                    staffExcelBean.getChangeEventsId(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "异动类型",
                    staffExcelBean.getChangeTypeId(), index).getMsg());

            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE, "2", "出生日期",
                    staffExcelBean.getBirthday(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "参加工作时间",
                    staffExcelBean.getWorkTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "本单位入职时间",
                    staffExcelBean.getCompanyInitiationTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "异动时间",
                    staffExcelBean.getChangeTime(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "参加组织时间",
//				staffExcelBean.getParticipationTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "排序号",
                    staffExcelBean.getOrderNumber(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "入党/团时间",
                    staffExcelBean.getJoinPartyTime(), index).getMsg());
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "任现职时间",
                    staffExcelBean.getTenureTime(), index).getMsg());
        }
        //判断完数据类型若有错直接返回
        if (msg.toString().length() > 0) {
            return new ImportResult(false, msg.toString());
        }
        //判重、先判断输入的编码是否有效(覆盖时需保证导入编码系统已存在，新增时需保证导入编码系统内不存在)

        //自身重复检查
        List<String> repeatList = ImportExcelUtil.findRepeat(codeList);
        for (String value : repeatList) {
            ArrayList<Integer> intList = new ArrayList();
            for (int i = 0; i < codeList.size(); ++i) {
                if (codeList.get(i) != null && codeList.get(i).equals(value)) {
                    intList.add(i + 2);
                }
            }
            msg.append(ImportExcelUtil.msgBuilder("2", intList.toString(), "人员编码", value, "重复!"));
        }
        //系统现有编码检查
        Map<String,String> staffFileDataMap = staffFilesList.parallelStream().collect(Collectors.toMap(staffFiles -> EncryptUtil.decryptBase64(staffFiles.getStaffCode(), BASE64_KEY), ZcglStaffManagement::getStaffName,(v1, v2)->v1));
        if(isCover) {
            //覆盖时若对应编码不存在，则报错
//			for(int i =0;i<codeList.size();i++) {
//				if (!staffFileDataMap.containsKey(codeList.get(i))) {
//					msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"不存在"));
//				}
//			}
        }else {
            //新增时若对应编码已存在，则报错
            for(int i =0;i<codeList.size();i++) {
                if (staffFileDataMap.containsKey(codeList.get(i))) {
                    msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"已存在"));
                }
            }
        }

        // 工作流状态检查
        Map<String,Integer> flowMap = staffFilesList.parallelStream()
                .collect(Collectors.toMap(staffFiles -> EncryptUtil.decryptBase64(staffFiles.getStaffCode()
                        , BASE64_KEY), ZcglStaffManagement::getStatus,(v1, v2)->v1));
        for(int i =0;i<codeList.size();i++) {
            if(flowMap.containsKey(codeList.get(i))){
                if(flowMap.get(codeList.get(i)) == FormStatusConstant.FINISH){
                    msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"已审批通过，无法导入"));
                }else if(flowMap.get(codeList.get(i)) == FormStatusConstant.FLOW){
                    msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"审核中，无法导入"));
                }
            }
        }

        //对象和字典是否存在校验
        int size=readExcels.size();
        int count=0;

        // 单位id加证件号
        List<String> keyList = new ArrayList<>();
        List<String> oldKeyList = new ArrayList<>();
        for (ZcglStaffManagement staffFiles : staffFilesList){
            oldKeyList.add(staffFiles.getCompanyNameId() + "-" + staffFiles.getDocumentNumber());
        }
        for(Object readExcel : readExcels){
            ZcglStaffManagementBean staffExcelBean =(ZcglStaffManagementBean)readExcel;
            int index = readExcels.indexOf(readExcel);
            //职务名称
//			if(StringUtils.isNotEmpty(staffExcelBean.getJobNameId()) && !codeMap.get("jobNameRef").contains(staffExcelBean.getJobNameId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职务名称", staffExcelBean.getJobNameId(), OBJECT_MSG));
//			}
            //证件类型
            if(StringUtils.isNotEmpty(staffExcelBean.getDocumentTypeId()) && !codeMap.get("documentTypeRef").contains(staffExcelBean.getDocumentTypeId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"证件类型", staffExcelBean.getDocumentTypeId(), OBJECT_MSG));
            }
            //性别
            if(StringUtils.isNotEmpty(staffExcelBean.getGenderId()) && !codeMap.get("genderRef").contains(staffExcelBean.getGenderId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"性别", staffExcelBean.getGenderId(), OBJECT_MSG));
            }
            //民族
            if(StringUtils.isNotEmpty(staffExcelBean.getNationId()) && !codeMap.get("nationRef").contains(staffExcelBean.getNationId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"民族", staffExcelBean.getNationId(), OBJECT_MSG));
            }
            //政治面貌
            if(StringUtils.isNotEmpty(staffExcelBean.getPoliticCountenanceId()) && !codeMap.get("politicCountenanceRef").contains(staffExcelBean.getPoliticCountenanceId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"政治面貌", staffExcelBean.getPoliticCountenanceId(), OBJECT_MSG));
            }
            //国籍
            if(StringUtils.isNotEmpty(staffExcelBean.getNationalityId()) && !codeMap.get("nationalityRef").contains(staffExcelBean.getNationalityId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"国籍", staffExcelBean.getNationalityId(), OBJECT_MSG));
            }
            //婚姻状态
            if(StringUtils.isNotEmpty(staffExcelBean.getMaritalStatusId()) && !codeMap.get("maritalStatusRef").contains(staffExcelBean.getMaritalStatusId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"婚姻状态", staffExcelBean.getMaritalStatusId(), OBJECT_MSG));
            }
            //最高学历
            if(StringUtils.isNotEmpty(staffExcelBean.getEducationalId()) && !codeMap.get("educationalRef").contains(staffExcelBean.getEducationalId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"最高学历", staffExcelBean.getEducationalId(), OBJECT_MSG));
            }
            //最高学位
            if(StringUtils.isNotEmpty(staffExcelBean.getDegreeId()) && !codeMap.get("degreeRef").contains(staffExcelBean.getDegreeId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"最高学位", staffExcelBean.getDegreeId(), OBJECT_MSG));
            }
            //管理类别
            if(StringUtils.isNotEmpty(staffExcelBean.getManagementCategoryId()) && !codeMap.get("managementCategoryRef").contains(staffExcelBean.getManagementCategoryId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"管理类别", staffExcelBean.getManagementCategoryId(), OBJECT_MSG));
            }
            //编制类型
            if(StringUtils.isNotEmpty(staffExcelBean.getCompilationTypeId()) && !codeMap.get("compilationTypeRef").contains(staffExcelBean.getCompilationTypeId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"编制类型", staffExcelBean.getCompilationTypeId(), OBJECT_MSG));
            }
            //人员类型
//			if(StringUtils.isNotEmpty(staffExcelBean.getStaffTypeId()) && !codeMap.get("staffTypeRef").contains(staffExcelBean.getStaffTypeId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"人员类型", staffExcelBean.getStaffTypeId(), OBJECT_MSG));
//			}
//			//人员类型
//			if(StringUtils.isNotEmpty(staffExcelBean.getStaffCategoryId()) && !codeMap.get("staffCategoryRef").contains(staffExcelBean.getStaffCategoryId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"人员类别", staffExcelBean.getStaffCategoryId(), OBJECT_MSG));
//			}
            //职务类别
            if(StringUtils.isNotEmpty(staffExcelBean.getJobCategoryId()) && !codeMap.get("jobCategoryRef").contains(staffExcelBean.getJobCategoryId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职务类别", staffExcelBean.getJobCategoryId(), OBJECT_MSG));
            }
            //职级
            if(StringUtils.isNotEmpty(staffExcelBean.getRankId()) && !codeMap.get("rankRef").contains(staffExcelBean.getRankId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职级", staffExcelBean.getRankId(), OBJECT_MSG));
            }
            //职等
//			if(StringUtils.isNotEmpty(staffExcelBean.getGradePositionsId()) && !codeMap.get("gradePositionsRef").contains(staffExcelBean.getGradePositionsId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职等", staffExcelBean.getGradePositionsId(), OBJECT_MSG));
//			}
            //异动事件
            if(StringUtils.isNotEmpty(staffExcelBean.getChangeEventsId()) && !codeMap.get("changeEventsRef").contains(staffExcelBean.getChangeEventsId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"异动事件", staffExcelBean.getChangeEventsId(), OBJECT_MSG));
            }
            //异动类型
            if(StringUtils.isNotEmpty(staffExcelBean.getChangeTypeId()) && !codeMap.get("changeTypeRef").contains(staffExcelBean.getChangeTypeId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"异动类型", staffExcelBean.getChangeTypeId(), OBJECT_MSG));
            }
            //健康状态
            if(StringUtils.isNotEmpty(staffExcelBean.getHealthConditionId()) && !codeMap.get("healthConditionRef").contains(staffExcelBean.getHealthConditionId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"健康状态", staffExcelBean.getHealthConditionId(), OBJECT_MSG));
            }


            //单位名称
            staffExcelBean.setCompanyNameId(StringUtil.cleanChars(staffExcelBean.getCompanyNameId()));
            if(nameMap.get("unitRef").containsKey(staffExcelBean.getCompanyNameId())){
                String companyName = staffExcelBean.getCompanyNameId();
                staffExcelBean.setCompanyNameId(nameMap.get("unitRef").get(staffExcelBean.getCompanyNameId()));
                if (!TokenUtil.getTokenOrgId().equals(staffExcelBean.getCompanyNameId())){
                    msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "单位名称", companyName, "不是当前登录单位"));
                }

            }else if(StringUtils.isNotEmpty(staffExcelBean.getCompanyNameId())){
                msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"单位名称", staffExcelBean.getCompanyNameId(), OBJECT_MSG));
            }
            // 部门名称 由于部门名称与单位关联，因此当单位名称错误时，会导致部门的校验出错，故需确保单位无误后才可对部门进行校验
            if(msg.length()==0) {
                if (StringUtils.isNotEmpty(staffExcelBean.getCompanyNameId())) {
                    if (deptUnitMap.containsKey(staffExcelBean.getCompanyNameId())) {
                        if (deptUnitMap.get(staffExcelBean.getCompanyNameId()).containsKey(staffExcelBean.getDepartmentNameId())) {
                            staffExcelBean.setDepartmentCode(deptUnitCodeMap.get(staffExcelBean.getCompanyNameId()).get(staffExcelBean.getDepartmentNameId()));
                            staffExcelBean.setDepartmentNameId(deptUnitMap.get(staffExcelBean.getCompanyNameId()).get(staffExcelBean.getDepartmentNameId()).toString());
                        } else if (StringUtils.isNotEmpty(staffExcelBean.getDepartmentNameId())) {
                            msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "部门名称", staffExcelBean.getDepartmentNameId(), OBJECT_MSG));
                        }
                    }
                    //else 单位不存在
                }
            }

//			if (CollectionUtil.isNotEmpty(keyList) && keyList.contains(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber())){
//				msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "证件号", staffExcelBean.getDocumentNumber(), "重复"));
//			}else {
//				keyList.add(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber());
//			}

//			if (CollectionUtil.isNotEmpty(oldKeyList) && oldKeyList.contains(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber())){
//				msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "证件号", staffExcelBean.getDocumentNumber(), "在该单位下已存在"));
//			}


            count++;
            int value = count * 100 / size;
            CacheUtil.put("progress","progress",progressId, value);
            log.info("校验进度："+value);
        }
        //...
        //统一放置报错
        if (msg.toString().length()>0) {
            return new ImportResult(false, msg.toString());
        }
        if (msg.toString().length()>0) {
            return new ImportResult(false, msg.toString());
        }
        return importResult;
    }
}
